/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Model.acl;

import java.io.IOException;
import java.util.HashMap;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContext;

/**
 *
 * @author Anthares
 */
public class ACL {
    private static final Logger LOG = Logger.getLogger(ACL.class.getName());
    private static Properties props= new Properties();
    private static HashMap<String, Ressource> ressources = new HashMap<String, Ressource>();
    private static HashMap<String, UserType> roles=new HashMap<String, UserType>();

    public static boolean hasRessource(String resName) {
        return ressources.containsKey(resName) || ressources.containsKey(controllerWideAccess(resName));
    }

    public static boolean hasAccess(String resName, String roleName) {
        UserType role = roles.get(roleName);
        if (role == null) {
            return false;
        }
        //if(resName.startsWith("/style")||resName.startsWith("/images")) return true;
        if(ressources.get("/*").hasAccess(role)) return true;
        if(hasRessource(controllerWideAccess(resName))&& ressources.get(controllerWideAccess(resName)).hasAccess(role)) return true;
        return ressources.get(resName).hasAccess(role);
    }

    public static void init(ServletContext ctx) { 
        ressources.clear();
        roles.clear();
        props.clear();
        try {
            props.load(ctx.getResourceAsStream("/WEB-INF/acl.properties"));

            String[] roleStrings = getProperty("roles").split(";");
            String[] ressourceStrings = getProperty("ressources").split(";");

            for (String string : roleStrings) {
                UserType role = createRole(string);
                roles.put(role.getType(), role);
            }

            for (String string : ressourceStrings) {
                Ressource res = new Ressource(string);

                String[] rights = getProperty(string).split(";");
                for (String right : rights) {
                    res.allow(roles.get(right));
                }
                ressources.put(string, res);
            }
        } catch (MalformedPropertiesException ex) {
            LOG.log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            LOG.log(Level.SEVERE, null, ex);
        }
    }

    private static String getProperty(String propName) throws MalformedPropertiesException {
        String property = props.getProperty(propName);
        if (property == null) {
            throw new MalformedPropertiesException(propName);
        }
        return property;
    }

    private static boolean roleInheritsFromAnother(String[] tab) {
        return tab.length > 1;
    }

    private static UserType createRole(String string) {
        String[] tab = string.split(":");
        UserType role;
        if (roleInheritsFromAnother(tab)) {
            UserType parent = roles.get(tab[1]);
            role = new UserType(tab[0], parent);
        } else {
            role = new UserType(tab[0]);
        }
        return role;
    }
    public static void log(){
        LOG.log(Level.INFO,"=== ACL Content ==");
        for (Ressource res : ressources.values()) {
            LOG.log(Level.INFO, "=== "+res.getName());
        }
    }

    private static String controllerWideAccess(String resName) {
        try{
        String[] splitted = resName.split("/");
        return "/"+splitted[1]+"/*";
        }catch(Exception e){
            return "";
        }
    }
}
